/*
 * Node.h
 *
 * Author: ansuz
 * Verantwortlicher: alle
 *
 * Diese Klasse stellt das grundlegende Gerüst für einen Knoten dar.
 * Sie muss abgeleitet werden, um benutzt werden zu können.
 */


#ifndef NODE_H_
#define NODE_H_

#include <rodos.h>
#include "resumer.h"
#include "worker-monitor-topics.h"

/**
 * Class Node
 * This class offers all functionality needed for a basic worker-monitor setup with StatusData
 * to be send.
 */
class Node : public Thread {
private:
	///Time after which a worker is considered dead/unresponsive if he does not publish workerAlive topics
	TTime workerTimeOut;
	///This nodes id
	long nodeID;
	///Mode of operation
	operationMode oMode;
	///Message buffer for the general message protocol
	Fifo<WMMessage,32> messageBuffer;
	///Subscriber for the general message protocol
	Subscriber messageSubscriber;
	///Message buffer for the workerAlive topic
	Fifo<long,32> workerAliveBuffer;
	///Subscriber for the workerAlive topic
	Subscriber workerAliveSubscriber;

	///Whether status data should be send or not
	bool sendStatusData;
	///Time when we published StatusData the last time
	long long timeLastPublish;
	///The time between two StatusData topic messages
	TTime timePublishInterval;



	/**
	 * Flushes the buffers so they are empty.
	 */
	void flushBuffers();

	/**
	 * Handles messages from the EGSE.
	 * @return true if this node a worker, false otherwise
	 */
	bool EGSEHandleMessages(WMMessage topicInput,bool isWorker);

	/**
	 * Handles messages for the worker.
	 * @return true if this node is still a worker, false otherwise
	 */
	bool wHandleMessages();

	/**
	 * Handles messages for the monitor.
	 * @return true if this node has become a worker, false otherwise
	 */
	bool mHandleMessages();

	/**
	 * Sets the time between publishing of StatusData topics.
	 * @param interval The time between two StatusData topics
	 */
	void setPeriodStatusInfo(long interval);

	/**
	 * Send StatusData to EGSE.
	 */
	void startSendStatusInfo();

	/**
	 * Stop sending StatusData.
	 */
	void stopSendStatusInfo();

	/**
	 * Publishes the given StatusData struct.
	 * @param data StatusData struct to publish
	 */
	void publishStatusData(StatusData* data);

public:

	///Initializes the member fields.
	Node(TTime workingTime);

	/**
	 * Initializes the node.
	 */
	void init();

	/**
	 * Handles the worker/monitor execution.
	 */
	void run();

	/**
	 * Does the work when this node is the worker.
	 * @return StatusData resulting from the work. If zero-pointer, it won't be published.
	 */
	virtual StatusData* work() = 0;
};

static LinkinterfaceUDP linkToNodes;
static Gateway topicGateway(&linkToNodes);
static Resumer gatewayResumer;

#endif /* NODE_H_ */
